// https://leetcode.cn/problems/print-foobar-alternately/
// Created by ade on 2022/11/2.
// 两个线程A和B，分别交替打印foo和bar

class FooBar {
private:
    int n;
    condition_variable cv;
    mutex mtx;
    int k = 1;

public:
    FooBar(int n) {
        this->n = n;

    }

    void foo(function<void()> printFoo) {
        for (int i = 0; i < n; i++) {
            unique_lock<mutex> lock(mtx);
            cv.wait(lock, [this](){return k == 1;});

            // printFoo() outputs "foo". Do not change or remove this line.
            printFoo();
            cv.notify_all();
            k = 2;
        }
    }

    void bar(function<void()> printBar) {
        for (int i = 0; i < n; i++) {
            unique_lock<mutex> lock(mtx);
            cv.wait(lock, [this](){return k == 2;});
            // printBar() outputs "bar". Do not change or remove this line.
            printBar();
            cv.notify_all();
            k = 1;
        }
    }
};